<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<meta http-equiv="X-UA-Compatible" content="ie=edge">
		<title>递归法</title>
		<style>
			.view ul ul {
				display: none;
			}

			.show {
				display: block !important;
			}
		</style>
	</head>
	<body>
		<div class="view">
			<!-- <ul>
            <li>
                <p>一级标题</p>
                <ul>
                    <li>
                        <p>二级标题</p>
                        <ul>
                            <li>
                                ...
                            </li>
                        </ul>
                    </li>
                </ul>
            </li>
        </ul> -->
		</div>
		<script>

			/*
				id: 当前项的id
				pid: 当前项父级的id	
			*/
			let data = [{
					id: 0,
					pid: -1,
					title: "微云"
				},
				{
					id: 1,
					pid: 0,
					title: "我的文档"
				},
				{
					id: 2,
					pid: 0,
					title: "我的音乐"
				},
				{
					id: 2999,
					pid: 1,
					title: "js程序设计"
				},
				{
					id: 29000,
					pid: 1,
					title: "js权威指南"
				},
				{
					id: 23333,
					pid: 2,
					title: "王杰"
				},
				{
					id: 244444,
					pid: 2,
					title: "张国荣"
				},
				{
					id: 3,
					pid: 2,
					title: "周杰伦"
				},
				{
					id: 4000,
					pid: 3,
					title: "稻香"
				},
				{
					id: 4,
					pid: 3,
					title: "发如雪"
				},
				{
					id: 600,
					pid: 3,
					title: "夜曲"
				}
			]
			
			
		/*递归+拼接法:
        思路：
		  1.递归获取父级下所有子级
            根据pid和id进行关联是否是父子级菜单
            最终是将所有递归获得的数据渲染到页面，所以递归函数需要有返回值;
          2.展开收缩：
            找到当前元素，如果是展开的，直接收缩；
            如果是收缩的，获取当前元素下的所有ul标签，将所有同级元素全部隐藏，再将当前元素进行显示
    */

    //注意！！！无论哪种思路实现都需注意不能生成一级菜单后直接渲染到页面，而是需要生成所有的DOM节点及内容后，才一次性渲染到页面。


			let view = document.querySelector(".view");
            
			//获取1个父级下子级
//			let getChild =function(id){
//			}
            
			let getChild = (id) => {
				//筛选pid等于id的情况就表示有子级
				return data.filter(item => item.pid == id);
			}
            console.log(getChild(-1)) // [{id: 0, pid: -1, title: "微云"}]
			//最终是不断根据pid等于id的情况进行递归，所以需要将这个写成一个函数不断进行递归
			//    let inner = '';
			//    data.forEach(item=>{
			//        inner +=`
			//             <ul>
			//                 <li>
			//                     <p>${item.title}</p>
			//                 </li>
			//             </ul>
			//        `;
			//    });

			//1.内部用递归法-查找所有父级下子级-最终要将所有递归到的inner渲染到页面，所以需要有返回值
			let createUl = (data) => {
				//不能在循环里面生成ul,否则会生成多个ul
				let inner = '<ul>';
				data.forEach(item => {
					inner +=
						`
                
                    <li>
                        <p>${item.title}</p>
                        ${
                            // 如果当前id还能找到对应pid的子级就继续查找
                            getChild(item.id)&&createUl(getChild(item.id))
                        }
                    </li>
        `;
				});
				inner += '</ul>';
				return inner;
			}
			console.log(createUl(getChild(-1))) //查找所有父级下子级
			//渲染写入
			view.innerHTML = createUl(getChild(-1));

			//2.点击展开与收缩功能
			let allP = document.querySelectorAll("p");
			allP.forEach(item => {
				item.onclick = () => {
					let curUl = item.nextElementSibling;
					if (curUl) {
						// 1. 当前是展开状态，点击之后就收缩起来
						if (curUl.classList.contains("show")) {
							curUl.classList.remove("show");
						} else {
							// 当前是收缩状态，就把所有的同级收缩起来，然后展开当前的
							let allUl = curUl.parentNode.parentNode.querySelectorAll("ul");

							//所有的同级收起来
							allUl.forEach(item => {
								item.classList.remove("show");
							});
							//展开当前
							curUl.classList.add("show");
						}
					}

				}
			})
		</script>
	</body>
</html>
